package halberd.filter;

import halberd.DataType;
import halberd.ImgFilter;
import halberd.data.ImgData;
import halberd.data.ImgDataFactory;
import halberd.utils.RGBUtils;

/**
 * 去白雾
 * 
 * @author jiang
 *
 */
public class DeFogFilter implements ImgFilter {
	public ImgData process(ImgData input) {
		if (!canProcess(input)) {
			return null;
		}
		ImgData result = ImgDataFactory.createImgData(input.getWidth(), input.getHeight());
		int[][][] ints = input.getDatas();
		defog(ints, result.getDatas(), input.getWidth(), input.getHeight());
		result.setDataType(DataType.GRAY);
		return result;
	}

	private boolean canProcess(ImgData input) {
		if (input == null) {
			return false;
		}
		DataType dt = input.getDataType();
		if (dt == DataType.RGB) {
			return true;
		}
		if (dt == DataType.RGBA) {
			return true;
		}
		return false;
	}

	private void defog(int[][][] src, int[][][] dst, int w, int h) {

		double toushelv = 0.6;
		double[][] dark = new double[w][h];
		for (int i = 0; i < w; i++) {
			for (int j = 0; j < h; j++) {
				int r = src[i][j][0];
				int g = src[i][j][1];
				int b = src[i][j][2];
				r = r < g ? r : g;
				r = r < b ? r : b;
				dark[i][j] = r;
			}
		}
		// 寻找暗中最亮
		int m = 0, n = 0;
		for (int i = 0; i < w; i += 1) {
			for (int j = 0; j < h; j += 1) {
				if (dark[i][j] > dark[m][n]) {
					n = j;
					m = i;
				}
			}
		}
		// 大气光强度估计值

		double max = dark[m][n];
		for (int i = 0; i < w; i++) {
			for (int j = 0; j < h; j++) {
				int r = src[i][j][0];
				int g = src[i][j][1];
				int b = src[i][j][2];

				double t = 1 - toushelv * (dark[i][j] / max);
				t = t < 0.1 ? 0.1 : t;
				dst[i][j][0] = RGBUtils.clamp255((int) ((r - (1 - t) * max) / t));
				dst[i][j][1] = RGBUtils.clamp255((int) ((g - (1 - t) * max) / t));
				dst[i][j][2] = RGBUtils.clamp255((int) ((b - (1 - t) * max) / t));
				dst[i][j][3] = src[i][j][3];
			}
		}
	}
}
